package org.nutboat.app;

import org.nutboat.asset.AssetManager;
import org.nutboat.controller.ControllerManager;
import org.nutboat.core.exception.UnInitializedException;
import org.nutboat.gui.GUIManager;
import org.nutboat.memory.MemoryManager;
import org.nutboat.renderer.RendererManager;
import org.nutboat.scene.SceneManager;
import org.nutboat.thread.ThreadManager;

public class Game {
	private static Game instance;
	
	private GameContext context;
	
	private GameSettings settings;
	
	private final MemoryManager memoryManager;
	private final ThreadManager threadManager;
	private final AssetManager assetManager;
	private final SceneManager sceneManager;
	private final RendererManager rendererManager;
	private final ControllerManager controllerManager;
	private final GUIManager guiManager;
	
	private final GameRunner runner;
	
	protected Game(GameContext context) {
		this.context = context;
		guiManager = new GUIManager(null);		
		controllerManager = new ControllerManager(guiManager);		
		rendererManager = new RendererManager(controllerManager);		
		sceneManager = new SceneManager(rendererManager);
		assetManager = new AssetManager(sceneManager);		
		threadManager = new ThreadManager(assetManager);		
		memoryManager = new MemoryManager(threadManager);
		runner = new GameRunner(memoryManager);
	}

	private static void check() {
		if (instance == null) {
			throw new UnInitializedException();
		}
	}
	
	public static GameContext getContext() {
		check();
		return instance.context;
	}
	
	public static GameSettings getSettings() {
		check();
		return instance.settings;
	}
	
	public static MemoryManager getMemoryManager() {
		check();
		return instance.memoryManager;
	}
	
	public static ThreadManager getThreadManager() {
		check();
		return instance.threadManager;
	}
	
	public static AssetManager getAssetManager() {
		check();
		return instance.assetManager;
	}
	
	public static ControllerManager getControllerManager() {
		check();
		return instance.controllerManager;
	}
	
	public static SceneManager getSceneManager() {
		check();
		return instance.sceneManager;
	}
	
	public static GUIManager getGUIManager() {
		check();
		return instance.guiManager;
	}
	
	public static GameRunner getRunner() {
		check();
		return instance.runner;
	}

	public static void run(Game game) {
		instance = game;
		check();
		instance.runner.on();
	}
		
	public static void exit() {	
		check();
		instance.runner.off();
		System.exit(0);
	}
}